package com.umfwechat.lightprogram.controller.selfdeploy;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.umfwechat.common.code.RetCode;
import com.umfwechat.common.constant.CommonConsts;
import com.umfwechat.common.constant.ConfigConsts;
import com.umfwechat.common.constant.PropertyConsts;
import com.umfwechat.common.constant.ValueConsts;
import com.umfwechat.common.prop.UmfPropModel;
import com.umfwechat.util.DesIDUtil;
import com.umfwechat.util.EmailXmlUtil;
import com.umfwechat.util.HttpHelper;
import com.umfwechat.util.PmUtils;
import com.umfwechat.util.PropertyUtil;
import com.umfwechat.util.ReqMessageUtil;
import com.umfwechat.util.RequestUtil;
import com.umfwechat.util.SaasPropertyUtil;
import com.umfwechat.util.StringUtil;
import com.umfwechat.util.email.MailSenderInfo;
import com.umfwechat.util.email.SendMailUtil;
import com.umfwechat.util.fileDownLoad.CaFilter;
import com.umpay.operation.model.merCnf.MerCnf;
import com.umpay.operation.model.merInfo.MerInfo;
import com.umpay.operation.model.merInfo.MerInfoEx;
import com.umpay.operation.model.offlinepay.tfilingmer.MerBankInf;
import com.umpay.operation.model.product.MerProduct;
import com.umpay.operation.service.colInfo.remote.ColInfoRemote;
import com.umpay.operation.service.merAcce.remote.SysParaServiceRemote;
import com.umpay.operation.service.merCnf.remote.MerCnfServiceRemote;
import com.umpay.operation.service.merInfo.remote.MerInfoServiceRemote;
import com.umpay.operation.service.offlinepay.tfilingmer.BankInfServiceRemote;
import com.umpay.operation.service.product.MerProductServiceRemote;
import com.umpay.operation.service.spapplyplat.remote.JoinFlowServiceRemote;

import com.umpay.sp.model.common.ReqMessage;
import com.umpay.sp.model.common.ResMessage;
import com.umpay.sp.model.saas.StoreInf;
import com.umpay.sp.service.saas.remote.AppChannelServiceRemote;
import com.umpay.sp.service.saas.remote.MerInfExServiceRemote;
import com.umpay.sp.service.saas.remote.StoreInfServiceRemote;
import com.umpay.sp.util.ConstEC;
import com.umpay.sp.util.Constants;
import com.umpay.sp.util.DateTimesUtil;
import com.umpay.sp.util.SerialUtil;
import com.umpay.sp.xml.XmlData;
import com.umpay.util.HttpUtil;
import com.umpay.util.TimeUtil;

/**
 * 自助部署Controller 第一步、第二步、第三步、第四步
 * @author ChenFuLong 2017-05-15
 * @version V1.0
 */
@Controller
@RequestMapping("/merchantDeploy")
public class MerchantJoinController {
	
	private static Logger logger = LoggerFactory.getLogger(MerchantJoinController.class);
	@Resource
	private StoreInfServiceRemote storeInfServiceRemote;
	
	@Resource
	private AppChannelServiceRemote appChannelServiceRemote;
	
	@Resource
	private MerInfExServiceRemote merInfExServiceRemote;
	
	// 开通商户相关
	@Resource
	private MerInfoServiceRemote merInfoServiceRemote;
	@Resource
	private SysParaServiceRemote sysParaServiceRemote;
	@Resource
	private ColInfoRemote colInfoRemote;
	@Resource
	private JoinFlowServiceRemote joinFlowServiceRemote;
	@Resource
	private MerProductServiceRemote merProductServiceRemote;
	@Resource
	private MerCnfServiceRemote merCnfServiceRemote;
	@Resource
	private BankInfServiceRemote bankInfServiceRemote;
	

/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 自助部署第一步：提交收款人信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + */
	
	/**
	 * 自助部署第一步：提交收款人信息
	 * @author ChenFuLong 2017-05-15
	 * @param session
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="/payeeInf", produces="application/json;charset=UTF-8")
	@ResponseBody
	@SuppressWarnings("unchecked")
	public JSONObject payeeInf(HttpSession session,HttpServletRequest request, HttpServletResponse response) throws Exception{
		logger.info("----#---------#--提交收款人信息，开始--#---------#--");
		JSONObject resultJson = new JSONObject();
		String reqJSON = (String) request.getAttribute("_requestData");
		JSONObject json = null;
		try {
			json = JSONObject.fromObject(reqJSON);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.error("----#---------#--请求提交收款人信息数据转换异常--#---------#--" + e);
			return resultJson;
		}
		String agentId = (String) json.get("loginAgentId");	//代理商编号
		String salesmanId = (String) json.get("loginUserId");	//业务员编号
		String payeeName = (String) json.get("payeeName");	//收款人姓名
		String payeeIdentity = (String) json.get("payeeIdentity");	//身份证号码
		String payeeInidcardValid = (String) json.get("payeeInidcardValid");	//证件有效期
		String payeeMobile = (String) json.get("payeeMobile");	//收款人手机
		String defultStore = "0";	//默认店铺	0默认店铺；1非默认店铺
		String merId = "";	//生成主商户号，即主商户店铺编号
		String storeId = "";	//生成子商户号，即店铺编号
		if (StringUtil.isEmpty(agentId) || StringUtil.isEmpty(salesmanId) || StringUtil.isEmpty(payeeName) || StringUtil.isEmpty(payeeIdentity) || StringUtil.isEmpty(payeeInidcardValid) || StringUtil.isEmpty(payeeMobile)) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.info("----#---------#--提交收款人信息，请求参数不足--#---------#--");
			return resultJson;
		}
		/*
		 * 通过身份证号查询此人是否已存在
		 */
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		req.put("payeeInidcard", DesIDUtil.encID(payeeIdentity));
		try {
			logger.info("----#---------#--根据身份证号查询店铺列表，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.getStoreInfList(req);
			logger.info("----#---------#--根据身份证号查询店铺列表，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据身份证号查询店铺列表异常--#---------#--" + e);
			return resultJson;
		}
		Integer totalSize = (Integer) res.getResMap().get("totalSize");
		if (res.getRetCode().equals("0000") && totalSize > 0) {	//判断返回码是否为0000且totalSize>0，说明已经开通过商户
			List<StoreInf> storeInfList = (List<StoreInf>) res.getResMap().get("storeInfList");
			//判断姓名、手机号、身份证号是否一致
			for (StoreInf storeInf : storeInfList) {
				if(!payeeName.equals(storeInf.getPayeeName()) 
						|| !payeeMobile.equals(storeInf.getPayeeMobileId()) 
						|| !DesIDUtil.encID(payeeIdentity).equals(storeInf.getPayeeInidcard())
						|| !payeeInidcardValid.equals(storeInf.getPayeeInidcardValid())){
					resultJson.put("retCode", "0001");
					resultJson.put("retMsg", "身份信息不一致，请重新输入");
					return resultJson;
				}
				if(storeInf.getRegisterProcsState().equals("02")){
					resultJson.put("retCode", "0000");
					resultJson.put("retMsg", "成功");
					resultJson.put("storeId", storeInf.getStoreId());	//店铺编号
					resultJson.put("payeeName", payeeName);	//收款人姓名
					resultJson.put("payeeIdentity", payeeIdentity);	//身份证号码
					resultJson.put("payeeInidcardValid", payeeInidcardValid);	//证件有效期
					return resultJson;
				}
				if (storeInf.getDefultStore().equals("0") || storeInf.getDefultStore() == "0") {	//判断是否有默认店铺
					defultStore = "1";
				}
				if(null != storeInf.getMerId() && !"".equals(storeInf.getMerId())){	//获取主商户号
					merId = storeInf.getMerId();
				}
			}
			if(null == merId  || "".equals(merId)){
				merId = storeInfList.get(0).getStoreId();
			}
		}else if(!res.getRetCode().equals("0000")){	//查询失败或异常
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}else{	//查询成功且未开过商户
			/*
			 * 通过收款人身份证号校验是否注册过U付账户
			 */
			ResMessage resCardNo = getMerInfExByCardNo(payeeIdentity);
			if ("0000".equals(resCardNo.getRetCode())) {
				if(resCardNo.getResMap().get("merInt").equals(0)){	//查询成功时，merInt=0则没有匹配数据
					/**
					 * 国政通身份认证
					 */
					Map<String,Object> resAuth = commAuth(payeeName, payeeIdentity);
					if (!"0000".equals(resAuth.get("retCode"))) {	//国政通身份认证不匹配
						resultJson.put("retCode", "0001");
						resultJson.put("retMsg", "身份信息不一致，请重新输入");
						return resultJson;
					}
				} //else {	//查询成功时，且有匹配数据，需要判断收款人姓名、收款人手机号是否一致？？？？
					
					
				//}
			}else{
				resultJson.put("retCode", "0001");
				resultJson.put("retMsg", "服务器异常，请稍后再试");
				return resultJson;
			}
			
			/**
			 * 开通主商户先生成主商户号（即首次创建主店铺）
			 */
//			merId = createMerId();	//生成主商户号，即主商户店铺编号
			merId = createNewStoreId();	//生成商户号，即主商户店铺编号
			if(StringUtil.isEmpty(merId)){
				resultJson.put("retCode", "0001");
				resultJson.put("retMsg", "服务器异常，请稍后再试");
				return resultJson;
			}
			
			/**
			 * 创建主商户前确认是否有此身份证的商户号
			 */
			ReqMessage reqMess = ReqMessageUtil.makeSpReq();
			reqMess.put("payeeInidcard", DesIDUtil.encID(payeeIdentity));
			ResMessage resMess = null;
			try {
				logger.info("----#---------#--根据身份证号查询店铺列表，请求参数：--#---------#--" + req);
				resMess = storeInfServiceRemote.getStoreInfList(req);
				logger.info("----#---------#--根据身份证号查询店铺列表，返回参数：--#---------#--" + res);
			} catch (Exception e) {
				resultJson.put("retCode", "0001");
				resultJson.put("retMsg", "服务器异常，请稍后再试");
				logger.error("----#---------#--根据身份证号查询店铺列表异常--#---------#--" + e);
				return resultJson;
			}
			Integer totalSizes = (Integer) resMess.getResMap().get("totalSize");
			if(resMess.getRetCode().equals("0000") && totalSizes > 0){
				resultJson.put("retCode", "0001");
				resultJson.put("retMsg", "网络异常，请重试！");
				logger.error("【根据身份证号查询店铺列表】totalSize：" + totalSizes);
				return resultJson;
			}
			
			
			/**
			 * 开通主商户（即首次创建主店铺）
			 */
			ResMessage resMer = saveStoreInf(merId, agentId, salesmanId, payeeName, payeeIdentity, payeeInidcardValid, payeeMobile);
			if (!"0000".equals(resMer.getRetCode())) {
				resultJson.put("retCode", "0001");
				resultJson.put("retMsg", "服务器异常，请稍后再试");
				return resultJson;
			}
		}
		/**
		 * 开通子商商户（即创建店铺）
		 */
//		storeId = createStoreId(merId);	//生成子商户号，即店铺编号
		storeId = createNewStoreId();	//生成商户号，即店铺编号
		if (StringUtil.isEmpty(storeId)) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}
		ResMessage resStroe = saveStoreInf(storeId, agentId, salesmanId, payeeName, payeeIdentity, payeeInidcardValid, payeeMobile, merId, defultStore);
		if(!"0000".equals(resStroe.getRetCode())){
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}
		resultJson.put("retCode", "0000");
		resultJson.put("retMsg", "成功");
		resultJson.put("storeId", storeId);	//店铺编号
		resultJson.put("payeeName", payeeName);	//收款人姓名
		resultJson.put("payeeIdentity", payeeIdentity);	//身份证号码
		resultJson.put("payeeInidcardValid", payeeInidcardValid);	//证件有效期
		return resultJson;
	}
	
	/**
	 * 通过收款人身份证号校验是否注册过U付账户
	 * @author ChenFuLong 2017-05-17
	 * @param payeeIdentity 身份证号
	 * @return
	 */
	public ResMessage getMerInfExByCardNo(String payeeIdentity){
		ResMessage res = new ResMessage();
		ReqMessage req = ReqMessageUtil.makeSpReq();
		try {
			req.put("controllercard",DesIDUtil.encID(payeeIdentity));	//身份证号（DES加密码）
			logger.info("----#---------#--收款人身份证号是否注册过U付账户，请求参数：--#---------#--" + req);
			res = merInfExServiceRemote.getMerInfExByCardNo(req);
			logger.info("----#---------#--收款人身份证号是否注册过U付账户，请求参数：--#---------#--" + res);
		} catch (Exception e) {
			res.put("retCode", "0001");
			res.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--收款人身份证号是否注册过U付账户异常--#---------#--" + e);
		}
		return res;
	}
	
	/**
	 * 国政通身份认证
	 * @author ChenFuLong 2017-05-16
	 * @param payeeName	姓名
	 * @param payeeIdentity	身份证号
	 * @return
	 */
	public Map<String, Object> commAuth(String payeeName, String payeeIdentity){
		Map<String,Object> resAuth = null;
		Date nowDate = new Date();
		try {
			Map<String, Object> reqAuth = new HashMap<String, Object>();
			reqAuth.put("rpid","W" + SerialUtil.getRpid(Constants.RPID_SEQ,10));
			reqAuth.put("reqDate",DateTimesUtil.formatDate(nowDate, DateTimesUtil.formatDay8Str));
			reqAuth.put("reqTime",DateTimesUtil.formatDate(nowDate, DateTimesUtil.formatTime6Str));
			String jQmerId = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","jQmerId", "");	//获取鉴权ID
			reqAuth.put("merId",jQmerId);	//商户号（随意传）
			reqAuth.put("productId","P15R00RZ");	//产品号
			reqAuth.put("busiMerId",jQmerId);	//业务商户号（文档中写的是：25998）
			reqAuth.put("authMode","3");	//验证方式
			reqAuth.put("accountName", payeeName);	//姓名
			reqAuth.put("bankIdentityCode",DesIDUtil.encID(payeeIdentity));	//身份证号（DES加密码）
			String url = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","id.auth", "");	//获取国政通身份认证链接
			logger.info("----#---------#--国政通身份认证，请求url：--#---------#--" + url);
			logger.info("----#---------#--国政通身份认证，请求参数：--#---------#--" + reqAuth);
			resAuth = HttpUtil.httpPostForm2Xml(url, reqAuth, "utf-8");
			logger.info("----#---------#--国政通身份认证，返回参数：--#---------#--" + resAuth);
		} catch (Exception e) {
			resAuth.put("retCode", "0001");
			resAuth.put("retMsg", "服务器异常，请稍后再试");
		}
		return resAuth;
	}
	
	
	/**
	 * 创建主商户
	 * @author ChenFuLong 2017-05-15
	 * @param storeId	店铺编号
	 * @param agentId	代理商编号
	 * @param salesmanId	业务员编号
	 * @param payeeName	收款人姓名
	 * @param payeeInidcard	收款人身份证号（加密）
	 * @param payeeInidcardValid	收款人身份证有效期
	 * @param payeeMobileId	收款人手机号码
	 * @return
	 */
	public ResMessage saveStoreInf(
			String storeId,
			String agentId,
			String salesmanId,
			String payeeName,
			String payeeInidcard,
			String payeeInidcardValid,
			String payeeMobileId
			){
		ResMessage res = null;
		ReqMessage req = ReqMessageUtil.makeSpReq();
		try {
			req.put(XmlData.STORE_ID, storeId);	//店铺编号，即主商户号
			req.put("agentId",agentId);
			req.put("salesmanId",salesmanId);
			req.put("payeeName",payeeName);
			req.put("payeeInidcard",DesIDUtil.encID(payeeInidcard));
			req.put("payeeInidcardValid",payeeInidcardValid);
			req.put("payeeMobileId",payeeMobileId);
			logger.info("----#---------#--创建主商户，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.saveStoreInf(req);
			logger.info("----#---------#--创建主商户，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			res.put("retCode", "0001");
			res.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--创建主商户异常--#---------#--" + e);
		}
		return res;
	}
	
	/**废弃此方法（此方法只能添加9家子商户）
	 * 生成主商户号（最大主商户号+10）
	 * @author ChenFulong
	 * @return
	 */
	public String createMerId(){
		logger.info("----#---------#--生成主商户号，开始：--#---------#--");
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		try {
			logger.info("----#---------#-获取最大的主商户编号，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.getMaxMainMerId(req);
			logger.info("----#---------#-获取最大的主商户编号，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			logger.error("----#---------#--生成主商户号异常--#---------#--" + e);
			return null;
		}
		if("0000".equals(res.getRetCode())){
			if (null != res.getResMap().get("maxMainMerId") && !"".equals(res.getResMap().get("maxMainMerId"))) {
				return Integer.valueOf((String) res.getResMap().get("maxMainMerId")) + 10 + "";
			}else {
				return "69000000";
			}
		}
		return null;
	}
	
	/**废弃此方法（此方法只能添加9家子商户）
	 * 生成子商户号，即店铺编号（最大子商户号+1）
	 * @author ChenFulong
	 * @param merId 主商户号
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String createStoreId(String merId){
		logger.info("----#---------#--生成子商户号，开始：--#---------#--");
		if (StringUtil.isEmpty(merId)) {
			return null;
		}
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		req.put("merId",merId);
		try {
			logger.info("----#---------#--获取自助部署列表，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.getStoreInfList(req);
			logger.info("----#---------#--获取自助部署列表，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			logger.error("----#---------#--获取自助部署列表异常--#---------#--" + e);
			return null;
		}
		Integer totalSize = (Integer) res.getResMap().get("totalSize");
		try {
			if(res.getRetCode().equals("0000")){
				if(totalSize > 0){	//有子商户
					if (totalSize == 9) {
						return "9999";	//第个商户只能开9家店
					}
					List<Integer> list = new ArrayList<Integer>();
					List<StoreInf> storeInfs = (List<StoreInf>) res.getResMap().get("storeInfList");
					for (int i = 0; i < storeInfs.size(); i++) {
						list.add(Integer.valueOf(storeInfs.get(i).getStoreId()));
					}
					return Collections.max(list) + 1 + "";
				}else {
					return Integer.valueOf(merId) + 1 + "";
				}
			}
		} catch (Exception e) {
			return null;
		}
		return null;
	}
	
	/**
	 * 生成商户号，主商户号与子商户号自增
	 * @author ChenFuLong
	 * @return
	 */
	public String createNewStoreId(){
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		for (int i = 69; i > 61; i--) {
			req.put("meridHeade", i + "");
			try {
				logger.info("----#---------#-获取最大的商户编号，请求参数：--#---------#--" + req);
				res = storeInfServiceRemote.getMaxMainMerIdByMeridHeade(req);
				logger.info("----#---------#-获取最大的商户编号，返回参数：--#---------#--" , res);
			} catch (Exception e) {
				logger.error("----#---------#--获取最大的商户编号异常--#---------#--" , e);
				return null;
			}
			if (!"0000".equals(res.getRetCode())) {
				logger.info("----#---------#-获取最大的商户编号，失败--#---------#--");
				return null;
			}
			String maxMainMerId = (String) res.getResMap().get("maxMainMerId");
			if (StringUtil.isNotEmpty(maxMainMerId)) {
				if (maxMainMerId.equals(i + "999999")) {
					continue;
				}else {
					return Integer.valueOf(maxMainMerId) + 1 + "";
				}
			}else {
				return i + "000000";
			}
		}
		return null;
	}
	
	/**
	 * 创建子商户，店铺信息
	 * @author ChenFuLong 2017-05-15
	 * @param storeId	店铺编号
	 * @param agentId	代理商编号
	 * @param salesmanId	业务员编号
	 * @param payeeName	收款人姓名
	 * @param payeeInidcard	收款人身份证号（加密）
	 * @param payeeInidcardValid	收款人身份证有效期
	 * @param payeeMobileId	收款人手机号码
	 * @param merId	主商户号
	 * @param defultStore	是否默认店铺：0是；1否
	 * @return
	 */
	public ResMessage saveStoreInf(
			String storeId,
			String agentId,
			String salesmanId,
			String payeeName,
			String payeeInidcard,
			String payeeInidcardValid,
			String payeeMobileId,
			String merId,
			String defultStore
			){
		ResMessage res = null;
		ReqMessage req = ReqMessageUtil.makeSpReq();
		try {
			req.put(XmlData.STORE_ID, storeId);	//店铺编号，即主商户号
			req.put("agentId",agentId);
			req.put("salesmanId",salesmanId);
			req.put("payeeName",payeeName);
			req.put("payeeInidcard",DesIDUtil.encID(payeeInidcard));
			req.put("payeeInidcardValid",payeeInidcardValid);
			req.put("payeeMobileId",payeeMobileId);
			req.put(XmlData.MER_ID,merId);
			req.put("defultStore",defultStore);
			req.put("registerProcsState","02");	//店铺状态：02待提交店铺
			req.put("type","0");//入网方式			
			req.put("isDel","0");//是否删除
			logger.info("----#---------#--创建子商户，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.saveStoreInf(req);
			logger.info("----#---------#--创建子商户，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			res.put("retCode", "0001");
			res.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--创建主商户异常--#---------#--" + e);
		}
		return res;
	}
	
	
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 自助部署第二步：提交店铺信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + */
	
	@RequestMapping(value="/updateStoreInf", produces="application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject updateStoreInf(HttpSession session,HttpServletRequest request, HttpServletResponse response) throws Exception{
		logger.info("----#---------#--提交店铺信息，开始--#---------#--");
		JSONObject resultJson = new JSONObject();
		String reqJSON = (String) request.getAttribute("_requestData");
		JSONObject json = null;
		try {
			json = JSONObject.fromObject(reqJSON);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.error("----#---------#--请求提交店铺信息数据转换异常--#---------#--" + e);
			return resultJson;
		}
		String storeId = (String) json.get("storeId");	//店铺编号
		String storeShortName = (String) json.get("storeShortName");	//商户简称
		String phone = (String) json.get("phone");	//客服电话-3期
		String storeCategory = ((String) json.get("storeCategory")).replace(",", "&");	//商户类别
		String storeAddress[] = ((String) json.get("storeAddress")).split(",");	//商户地址：省，市，区
		String storeFullAddress = (String) json.get("storeFullAddress");	//详细地址
		String email = (String) json.get("email");	//商户邮箱
		String storeType = (String) json.get("storeType");	//商户类型：0小微；1个体（企业）
		String licenseNo = (String) json.get("licenseNo");	//营业执照号
		String storeName = (String) json.get("storeName");	//商户全称
		String registerDate = (String) json.get("registerDate");	//注册日期
		String storeKind = (String) json.get("storeKind");	//主营业务
		String registerAddress = (String) json.get("registerAddress");	//注册地址
		String storeMan = (String) json.get("storeMan");	//经营者姓名
		String storeManIdentity = (String) json.get("storeManIdentity");	//身份证号码
		String storeManIdentityValid = (String) json.get("storeManIdentityValid");	//证件有效期
		String longitude = (String) json.get("longitude");	//经度
		String latitude = (String) json.get("latitude");	//纬度
		String mobileLocation = (String) json.get("mobileLocation");	//定位地址
		String labelOne=(String)json.get("labelOne");   //标签一
		String labelTwo=(String)json.get("labelTwo");   //标签二
		String formId = (String) json.get("formId");	//表单编号
		String loginUserId = (String) json.get("loginUserId");	//表单编号
		String isOpenPos = (String) json.get("isPos");	//否开通POS
		if (StringUtil.isEmpty(storeId) || StringUtil.isEmpty(storeShortName) || StringUtil.isEmpty(storeFullAddress) || StringUtil.isEmpty(storeType)) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.info("----#---------#--提交店铺信息，请求参数不足--#---------#--");
			return resultJson;
		}
		if("1".equals(storeType)){
			//根据经营者身份证号，查询店铺表中是否有店铺；规则CATEGORY_MAN_CARDNO = #categoryManCardno# OR PAYEE_INIDCARD = #categoryManCardno#
			ReqMessage reqCount = ReqMessageUtil.makeSpReq();
			ResMessage resCount = null;
			reqCount.put(XmlData.CATEGORY_MAN_CARDNO, DesIDUtil.encID(storeManIdentity));
			try {
				logger.info("----#---------#--根据根据经营者身份证号查询店铺，请求参数：--#---------#--" + reqCount);
				resCount = storeInfServiceRemote.getStoreInfListByCategoryManCardno(reqCount);
				logger.info("----#---------#--根据根据经营者身份证号查询店铺，返回参数：--#---------#--" + resCount);
			} catch (Exception e) {
				resultJson.put("retCode", "00434101");
				resultJson.put("retMsg", "服务器异常，请稍后再试");
				logger.error("----#---------#--根据根据经营者身份证号查询店铺数量--#---------#--" , e);
				return resultJson;
			}
			if(!"0000".equals(resCount.getRetCode())){
				resultJson.put("retCode", "00434101");
				resultJson.put("retMsg", "服务器异常，请稍后再试");
				return resultJson;
			}
			List<StoreInf> storeInfList = (List<StoreInf>) resCount.getValue(XmlData.STORE_INF_LIST);
			//如果查询到了，就说明该身份证号以前走过国政通校验，没有查询到，就需要校验该身份证号国政通
			if(storeInfList==null || storeInfList.size()==0){
				/**
				 * 国政通身份认证
				 */
				Map<String,Object> resAuth = commAuth(storeMan, storeManIdentity);
				if (!"0000".equals(resAuth.get("retCode"))) {	//国政通身份认证不匹配
					resultJson.put("retCode", "00434116");
					resultJson.put("retMsg", "经营者身份信息不一致，请重新输入");
					return resultJson;
				}
			}else{
				for (StoreInf storeInf : storeInfList) {
					if(storeMan.equals(storeInf.getPayeeName()) && storeManIdentityValid.equals(storeInf.getPayeeInidcardValid())){
						break;
					}else if(storeMan.equals(storeInf.getCategoryManName()) && storeManIdentityValid.equals(storeInf.getCategoryInidcardValid())){
						break;
					}else{
						resultJson.put("retCode", "00434116");
						resultJson.put("retMsg", "经营者身份信息不一致，请重新输入");
						return resultJson;
					}
				}
			}
		}
		/**
		 * 通过店铺编号获取店铺详情
		 */
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		req.put("storeId", storeId);
		try {
			logger.info("----#---------#--根据店铺编号查询店铺详情，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.getStoreInfByPri(req);
			logger.info("----#---------#--根据店铺编号查询店铺详情，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据店铺编号查询店铺详情异常--#---------#--" + e);
			return resultJson;
		}
		if(!"0000".equals(res.getRetCode())){	//查询店铺详情失败或异常
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}else if(res.getResMap().get("storeInf") == null){	//未获取到店铺信息，storeId不存在
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "获取店铺信息失败");
			return resultJson;
		}
		
		StoreInf storeInf = (StoreInf) res.getResMap().get("storeInf");
		
		/**
		 * 如果用户开小微店铺，则需要判断一下用户有没有开通提前结算产品
		 * 如果用户开通了提前结算产品，则不能再开小微商户
		 * @author ChenFuLong
		 * @version MSX00001145
		 */
		if ("0".equals(storeType)) {
			// 收入结算产品编号
			String productId = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.PRODUCTID_ADVANCESETTLE);
			logger.info("【获取收入结算产品编号】:productId_advanceSettle = " + productId);
			ReqMessage reqChanne = ReqMessageUtil.makeSpReq();
			ResMessage resChanne = null;
			reqChanne.put(CommonConsts.APPSYSID,storeInf.getMerId());
			reqChanne.put(CommonConsts.PRODUCTID,productId);
			try {
				logger.info("【根据主键查询渠道表接口】请求参数：" + reqChanne);
				resChanne =appChannelServiceRemote.queryByAppSysId(reqChanne);
				logger.info("【根据主键查询渠道表接口】返回参数：" + resChanne);
			} catch (Exception e) {
				resultJson.put(CommonConsts.RETCODE, "0001");
				resultJson.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
				logger.error("【根据主键查询渠道表】异常", e);
				return resultJson;
			}
			if (RetCode.SUCCESS.equals(resChanne.getRetCode())) {	//返回成功，说明已经开通了提前结算产品
				resultJson.put(CommonConsts.RETCODE, "0001");
				resultJson.put(CommonConsts.RETMSG, "您已开通了提前结算产品，暂不支持同时开通小微店铺");
				logger.error("【根据主键查询渠道表】成功，说明：已开通了提前结算产品，暂不支持同时开通小微店铺");
				return resultJson;
			}
		}
		
		/**
		 * 如果用户开小微店铺，则需要判断一下用户有没有开通基金产品
		 * 如果用户开通了基金产品，则不能再开小微商户
		 * @author ChenFuLong
		 * @version SKS00000039
		 */
		if ("0".equals(storeType)) {
			String fundOpenAccSearch = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDOPENACCSEARCH);	//基金企业、个人开户信息查询接口路径
			String fundNo = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDNO);	//基金编号
			String fundMerId = UmfPropModel.INSTANCE.getPropValue(ConfigConsts.FUNDMERID);	//基金公司商户号
			Map<String, Object> params = new HashMap<String, Object>();
			//输入参数
			com.umfwechat.common.ReqMessage makeFundReq = ReqMessageUtil.makeFundReq();
			Map<String, Object> resFund=null;
			params.put(CommonConsts.RPID, makeFundReq.getRpid());//流水号
			params.put(CommonConsts.REQDATE, makeFundReq.getReqDate());//日期
			params.put(CommonConsts.REQTIME, makeFundReq.getReqTime());//时间
			params.put(CommonConsts.FUNDNO,fundNo);
			params.put(CommonConsts.FUNDMERID,fundMerId);
			params.put(CommonConsts.USERMERID,storeInf.getMerId());
			params.put(CommonConsts.MERUSERID,storeInf.getMerId());
			params.put(CommonConsts.BPRODUCTID,PropertyConsts.BPRODUCTID);
			try {
				logger.info("【基金企业/个人开户信息查询】请求参数：params="+params+ "访问路径url="+ fundOpenAccSearch);	
				resFund = HttpUtil.httpPostXStream2XStream(fundOpenAccSearch,params,"utf-8");
				logger.info("【基金企业/个人开户信息查询】返回参数：" + resFund);
				if(RetCode.SUCCESS.equals(StringUtil.trim(resFund.get(CommonConsts.RETCODE)))) { // 查询成功
					resultJson.put(CommonConsts.RETCODE, "0001");
					resultJson.put(CommonConsts.RETMSG, "您已开通了基金产品，暂不支持同时开通小微店铺");
					logger.info("【查询商户是否开通基金产品】成功，说明：已开通了基金产品，暂不支持同时开通小微店铺");
					return resultJson;
				}
			} catch (Exception e) {
				resultJson.put(CommonConsts.RETCODE, "0001");
				resultJson.put(CommonConsts.RETMSG, "服务器异常，请稍后再试");
				logger.error("【查询商户是否开通基金产品】异常", e);
				return resultJson;
			}
		}
		
		/**
		 * 根据主商户号和商户简称查询是否已存在
		 */
		ReqMessage reqCountStore = ReqMessageUtil.makeSpReq();
		ResMessage resCountStore = null;
		reqCountStore.put("storeShortName",storeShortName);	//商户简称
		reqCountStore.put("merId",storeInf.getMerId());	//主商户号
		try {
			logger.info("----#---------#--根据主商户号和商户简称查询是否已存在，请求参数：--#---------#--" + reqCountStore);
			resCountStore = storeInfServiceRemote.countStoreInfByStoreNameAndMerId(reqCountStore);
			logger.info("----#---------#--根据主商户号和商户简称查询是否已存在，返回参数：--#---------#--" + resCountStore);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据主商户号和商户简称查询是否已存在异常--#---------#--" + e);
			return resultJson;
		}
		if ("0000".equals(resCountStore.getRetCode())) {
			Integer storeCount = (Integer) resCountStore.getResMap().get("storeCount");
			if (storeCount > 0) {
				resultJson.put("retCode", "0001");
				resultJson.put("retMsg", "商户简称已存在");
				return resultJson;
			}
		}else {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}
		
		storeInf.setStoreId(storeId);
		storeInf.setStoreShortName(storeShortName);	//商户简称
		storeInf.setStoreCategory(storeCategory);	//商户类别
		storeInf.setPhone(phone);//客服电话	
		storeInf.setStoreAddrProv(storeAddress[0]);	//商户地址：省
		storeInf.setStoreAddrCity(storeAddress[1]);	//商户地址：市
		//修复bug 东莞下没区
		if(storeAddress.length == 3){
			storeInf.setStoreAddrArea(storeAddress[2]);	//商户地址：区	
		}
		storeInf.setStoreFullAddr(storeFullAddress);	//详细地址
		storeInf.setLongiTude(longitude);	//经度
		storeInf.setLatiTude(latitude);	//纬度
		storeInf.setMobileLocation(mobileLocation);	//定位地址
		storeInf.setStoreType(storeType);	//商户类型：0小微；1个体（企业）
		storeInf.setRegisterProcsState("03");	//店铺状态
		storeInf.setStoreGrade("B");	//商户评级：A有营业执照；B无营业执照
		if(storeType.equals("1")){
			storeInf.setStoreGrade("A");	//商户评级：A有营业执照；B无营业执照
			storeInf.setLicenseNo(licenseNo);	//营业执照号
			storeInf.setStoreFullName(storeName);	//商户全称
			storeInf.setRegisterDate(registerDate);	//注册日期
			storeInf.setMainBusiness(storeKind);	//主营业务
			storeInf.setRgstaddress(registerAddress);	//注册地址
			storeInf.setCategoryManName(storeMan);	//经营者姓名
			storeInf.setCategoryManCardno(DesIDUtil.encID(storeManIdentity));	//身份证号码(加密)
			storeInf.setCategoryInidcardValid(storeManIdentityValid);	//证件有效期
			storeInf.setIsOpenPos(isOpenPos);//是否要开POS
		}
		/**
		 * 修改（更新）店铺信息
		 */
		storeInf.setIntime(null);
		storeInf.setModtime(null);
		storeInf.setLabelOne(labelOne);
		storeInf.setLabelTwo(labelTwo);
		storeInf.setEmail(email);//商户邮箱地址
		storeInf.setFormId(formId);//表单编号
		storeInf.setLastModuser(loginUserId);
		Map<String, String> storeMap = SaasPropertyUtil.javaBeanToMap(storeInf);
		req.putAll(storeMap);
		try {
			logger.info("----#---------#--根据店铺编号更新店铺信息，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.updateStoreInf(req);
			logger.info("----#---------#--根据店铺编号更新店铺信息，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据店铺编号更新店铺信息异常--#---------#--" + e);
			return resultJson;
		}
		if (!"0000".equals(res.getRetCode())) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}
		resultJson.put("retCode", "0000");
		resultJson.put("retMsg", "成功");
		resultJson.put("payeeName", storeInf.getPayeeName());	//收款人姓名
		resultJson.put("storeMan", storeInf.getCategoryManName());	//经营者姓名
		resultJson.put("storeType", storeInf.getStoreType());	//商户类型：0小微；1个体
		resultJson.put("storeId", storeId);
		if (DesIDUtil.decID(storeInf.getPayeeInidcard()).equals(storeManIdentity)) {
			resultJson.put("isAuthorize", "0");
		}else {
			resultJson.put("isAuthorize", "1");
		}
		return resultJson;
	}
	
	
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 自助部署第三步：上传证照信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + */
	
	@RequestMapping(value="/uploadImg", produces="application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject uploadImg(HttpSession session,HttpServletRequest request, HttpServletResponse response) throws Exception{
		logger.info("----#---------#--提交证照信息，开始--#---------#--");
		JSONObject resultJson = new JSONObject();
		String reqJSON = (String) request.getAttribute("_requestData");
		JSONObject json = null;
		try {
			json = JSONObject.fromObject(reqJSON);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.error("----#---------#--请求上传证照信息数据转换异常--#---------#--" + e);
			return resultJson;
		}
		String imgHttpUrl = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","img.http.url", "");	//获取图片服务器Http地址
		String imgFileUrl = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","saasPlat.comp.uploadPath", "");	//获取图片服务器存储地址
		logger.info("----#---------#--获取自助部署提交证照信息地址：--#---------#--" + imgHttpUrl + "--#---------#--" + imgFileUrl);
		if(StringUtil.isEmpty(imgHttpUrl) || StringUtil.isEmpty(imgFileUrl)){	//获取配置信息失败则返回提示信息
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "获取证照信息失败");
			return resultJson;
		}
		DiskFileItemFactory factory = new DiskFileItemFactory();	//创建一个DiskFileItemFactory工厂  
		ServletFileUpload upload = new ServletFileUpload(factory);	//创建一个文件上传解析器  
		upload.setHeaderEncoding("UTF-8");
		FileItem file = null;	//图片
		String img = (String) json.get("img");	//图片文件（对应库中字段）
		String storeId = (String) json.get("storeId");	//店铺编号
		String imgName = UUID.randomUUID().toString().replace("-", "") + ".jpg";
		String imageUrl = imgFileUrl + storeId + "/" + imgName;	//生成图片的URL（路径：配置文件中的路径 + 店铺编号 + 文件名名称）
		List<FileItem> items = upload.parseRequest(request);	//得到FileItem的集合items
		for (FileItem item : items) {
			String name = item.getFieldName();
			if ("file".equals(name)) {
				file = item;
			}
		}
		if (StringUtil.isEmpty(img) || StringUtil.isEmpty(storeId) || file == null) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			return resultJson;
		}
		if (!img.equals("payeeCardPhotoFront")	//收款人身份证正面
			&& !img.equals("payeeCardPhotoCon")	//收款人身份证反面
			&& !img.equals("categoryCardPhotoFront")	//经营者身份证正面
			&& !img.equals("categoryCardPhotoCon")	//经营者身份证方面
			&& !img.equals("shopSignPhotoFront")	//店铺招牌照片
			&& !img.equals("shopSignPhotoCon")	//店铺内景照片
			&& !img.equals("busiLicensePhoto")	//营业执照照片
			&& !img.equals("authCertPhoto")) {	//授权函照片
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			return resultJson;
		}
		logger.info("----#---------#--将图片存入服务器并返回URL，开始--#---------#--");
		String imgUrl = ShowImgController.getImgUrl(file, imageUrl, imgHttpUrl);
		logger.info("----#---------#--将图片存入服务器并返回URL，结束--#---------#--" + imgUrl);
		if(StringUtil.isEmpty(imgUrl)){
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "图片上传失败");
			return resultJson;
		}
		
		/**
		 * 通过店铺编号获取店铺详情
		 */
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		req.put("storeId", storeId);
		try {
			logger.info("----#---------#--根据店铺编号查询店铺详情，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.getStoreInfByPri(req);
			logger.info("----#---------#--根据店铺编号查询店铺详情，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据店铺编号查询店铺详情异常--#---------#--" + e);
			return resultJson;
		}
		if(!"0000".equals(res.getRetCode())){	//查询店铺详情失败或异常
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}else if(res.getResMap().get("storeInf") == null){	//未获取到店铺信息，storeId不存在
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "获取店铺信息失败");
			return resultJson;
		}
		StoreInf storeInf = (StoreInf) res.getResMap().get("storeInf");
		storeInf.setStoreId(storeId);
		if(img.equals("payeeCardPhotoFront")){	//收款人身份证正面
			storeInf.setPayeeCardPhotoFront(imgName);
		}else if (img.equals("payeeCardPhotoCon")) {	//收款人身份证反面
			storeInf.setPayeeCardPhotoCon(imgName);
		}else if (img.equals("categoryCardPhotoFront")) {	//经营者身份证正面
			storeInf.setCategoryCardPhotoFront(imgName);
		}else if (img.equals("categoryCardPhotoCon")) {	//经营者身份证方面
			storeInf.setCategoryCardPhotoCon(imgName);
		}else if (img.equals("shopSignPhotoFront")) {	//店铺招牌照片
			storeInf.setShopSignPhotoFront(imgName);
		}else if (img.equals("shopSignPhotoCon")) {	//店铺内景照片
			storeInf.setShopSignPhotoCon(imgName);
		}else if (img.equals("busiLicensePhoto")) {	//营业执照照片
			storeInf.setBusiLicensePhoto(imgName);
		}else if (img.equals("authCertPhoto")) {	//授权函照片
			storeInf.setAuthCertPhoto(imgName);
		}else {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			return resultJson;
		}
		
		storeInf.setIntime(null);
		storeInf.setModtime(null);
		Map<String, String> storeMap = SaasPropertyUtil.javaBeanToMap(storeInf);
		req.putAll(storeMap);
		try {
			logger.info("----#---------#--根据店铺编号更新证照信息，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.updateStoreInf(req);
			logger.info("----#---------#--根据店铺编号更新证照信息，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据店铺编号更新证照信息异常--#---------#--" + e);
			return resultJson;
		}
		if(!"0000".equals(res.getRetCode())){
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "图片上传失败");
			return resultJson;
		}
		resultJson.put("retMsg", "成功");
		resultJson.put("retCode", "0000");
		resultJson.put("imgUrl", imgUrl);
		return resultJson;
	}
	
	
/* + + + + + + + + + + + + + + + + + + + + + + + + + + + 自助部署第四步：上传证照后提交信息 + + + + + + + + + + + + + + + + + + + + + + + + + + + */
	
	@RequestMapping(value="/submitImg", produces="application/json;charset=UTF-8")
	@ResponseBody
	public JSONObject submitImg(HttpSession session,HttpServletRequest request, HttpServletResponse response) throws Exception{
		logger.info("----#---------#--上传证照后提交信息，开始--#---------#--");
		JSONObject resultJson = new JSONObject();
		String reqJSON = (String) request.getAttribute("_requestData");
		JSONObject json = null;
		try {
			json = JSONObject.fromObject(reqJSON);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.error("----#---------#--请求上传证照后提交信息数据转换异常--#---------#--" + e);
			return resultJson;
		}
		String storeId = (String) json.get("storeId");	//店铺编号
		
		if (StringUtil.isEmpty(storeId)) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "请求参数不足");
			logger.info("----#---------#--上传证照后提交信息，请求参数不足--#---------#--");
			return resultJson;
		}
		/**
		 * 通过店铺编号获取店铺详情
		 */
		ReqMessage reqStore = ReqMessageUtil.makeSpReq();
		ResMessage resStore = null;
		reqStore.put("storeId",storeId);
		try {
			logger.info("----#---------#--根据店铺编号查询店铺详情，请求参数：--#---------#--" + reqStore);
			resStore = storeInfServiceRemote.getStoreInfByPri(reqStore);
			logger.info("----#---------#--根据店铺编号查询店铺详情，返回参数：--#---------#--" + resStore);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据店铺编号查询店铺详情异常--#---------#--" + e);
			return resultJson;
		}
		if(!"0000".equals(resStore.getRetCode())){	//查询店铺详情失败或异常
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}else if(resStore.getResMap().get("storeInf") == null){	//未获取到店铺信息，storeId不存在
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "获取店铺信息失败");
			return resultJson;
		}
		
		StoreInf storeInf = (StoreInf) resStore.getResMap().get("storeInf");	//子商户详情
		
		/**
		 * 通过主商户号获取主商户详情
		 */
		ReqMessage reqMer = ReqMessageUtil.makeSpReq();
		ResMessage resMer = null;
		reqMer.put("storeId",storeInf.getMerId());
		try {
			logger.info("----#---------#--根据店铺编号查询店铺详情，请求参数：--#---------#--" + reqMer);
			resMer = storeInfServiceRemote.getStoreInfByPri(reqMer);
			logger.info("----#---------#--根据店铺编号查询店铺详情，返回参数：--#---------#--" + resMer);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据主商户号查询主商户详情异常--#---------#--" + e);
			return resultJson;
		}
		if(!"0000".equals(resStore.getRetCode())){	//查询店铺详情失败或异常
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}else if(resStore.getResMap().get("storeInf") == null){	//未获取到店铺信息，storeId不存在
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "获取店铺信息失败");
			return resultJson;
		}
		
		StoreInf merInf = (StoreInf) resMer.getResMap().get("storeInf");	//主商户详情
		
		/**
		 * 调用主商户开通子流程，共8步
		 */
		logger.info("----#---------#--主商户开通子流程共8步，开始--#---------#--");
		String merErrorMsg = registerMerJoin(merInf);
		logger.info("----#---------#--主商户开通子流程共8步，结束--#---------#--");
		if(StringUtil.isNotEmpty(merErrorMsg)){
			/**
			 * 将错误信息插入审批流程表
			 */
			addJoinFlowForCheckMer(storeInf, merErrorMsg);
			
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", merErrorMsg);
			logger.info("----#---------#--店铺开通子流程，失败--#---------#--" + merErrorMsg);
			return resultJson;
		}
		createCust(merInf.getStoreId(), merInf.getPayeeName());//同步客户信息到crm,58工单新加
		
		/**
		 * 调用店铺开通子流程（主商户开通共8步；店铺开通共5步）
		 */
		logger.info("----#---------#--店铺开通子流程共5步，开始--#---------#--");
		String storeErrorMsg = registerStoreJoin(storeInf);
		logger.info("----#---------#--店铺开通子流程共5步，结束--#---------#--");
		if (StringUtil.isNotEmpty(storeErrorMsg)) {
			/**
			 * 将错误信息插入审批流程表
			 */
			addJoinFlowForCheckMer(storeInf, storeErrorMsg);
			
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", storeErrorMsg);
			logger.info("----#---------#--店铺开通子流程，失败--#---------#--" + storeErrorMsg);
			return resultJson;
		}
		createMerCustRel(storeInf.getMerId(), storeInf.getPayeeName(), storeInf.getStoreId(), storeInf.getStoreShortName());
		/**
		 * 更新店铺状态为04待开通产品
		 */
		storeInf.setStoreId(storeId);
		storeInf.setRegisterProcsState("04");	//更新店铺状态为04，待开通产品
		storeInf.setIntime(null);
		storeInf.setModtime(null);
		Map<String, String> storeMap = SaasPropertyUtil.javaBeanToMap(storeInf);
		ReqMessage req = ReqMessageUtil.makeSpReq();
		ResMessage res = null;
		req.putAll(storeMap);
		try {
			logger.info("----#---------#--根据店铺编号更新店铺状态为04，请求参数：--#---------#--" + req);
			res = storeInfServiceRemote.updateStoreInf(req);
			logger.info("----#---------#--根据店铺编号更新店铺状态为04，返回参数：--#---------#--" + res);
		} catch (Exception e) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			logger.error("----#---------#--根据店铺编号更新店铺状态为04异常--#---------#--" + e);
			return resultJson;
		}
		if (!"0000".equals(res.getRetCode())) {
			resultJson.put("retCode", "0001");
			resultJson.put("retMsg", "服务器异常，请稍后再试");
			return resultJson;
		}
		//判断是否有邮箱
		logger.info("---开户邮件参数------------------" + storeInf.toString());
		String email = storeInf.getEmail();
		logger.info("----开户邮件参数------------------" + email+ storeInf.getEmail());
		if(email != null &&  !"".equals(email)){		
			//第一次不成功发送第二次
			logger.info("----开户第一次发送邮件-----start---------#--");
			boolean fristType = sendEmail(storeInf);
			logger.info("----开户第一次发送邮件-----end------------结果=" + fristType);
			if(!fristType){
				logger.info("----开户第二次发送邮件-----start---------#--");
				boolean senType  = sendEmail(storeInf);
				logger.info("----开户第二次发送邮件-----start---------结果=" + senType);
			}
			
		}
		
		resultJson.put("retCode", "0000");
		resultJson.put("retMsg", "成功");
		resultJson.put("storeId", storeId);
		return resultJson;
	}
	
	/**
	 * 主商户开通子流程
	 * 1、添加商户正式信息
	 * 2、添加商户账户信息
	 * 3、添加商户辅助信息
	 * 4、添加商户配置、生成证书
	 * 5、添加商户对账信息
	 * 6、添加商户产品关系
	 * 7、添加商户签约产品、基础产品费率信息（只配置基础产品）
	 * 8、配置商户与联动商户号的银商关系
	 * @param storeInf 店铺详情
	 * @return
	 * @throws Exception
	 */
	public String registerMerJoin(StoreInf merInf){
		String error = "";
		logger.info("==★====★====★==主商户注册操作【1】：添加主商户正式信息");
		error = insertMerInfoAndEx(merInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★====★==主商户注册操作【1】：添加主商户正式信息操作失败");
			return "添加商户正式信息失败";
		}
		
		logger.info("==★====★★====★==主商户注册操作【2】：添加主商户账户信息");
		error = toOpenMerAccount(merInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★====★==主商户注册操作【2】：添加主商户账户信息操作失败");
			return "添加商户账户信息失败";
		}
			
		logger.info("==★====★★★====★==主商户注册操作【3】：添加主商户辅助信息");
		error = addSysPara(merInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★====★==主商户注册操作【3】：添加主商户辅助信息操作失败");
			return "添加商户辅助信息失败";
		}
		
		logger.info("==★====★★★★★====★==主商户注册操作【4】：添加主商户配置、生成证书");
		error = addMerCnf(merInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★★★====★==主商户注册操作【4】：添加主商户配置、生成证书，操作失败");
			return "添加商户配置、生成证书失败";
		}
		
		logger.info("==★====★★★★★★====★==主商户注册操作【5】：添加主商户对账信息");
		error = addMerRecon(merInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★★★★====★==主商户注册操作【5】：添加主商户对账信息，操作失败");
			return "添加商户对账信息失败";
		}
		
		String productId = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","productId.saas.Base", "");	//获取基础产品ID
		String productIds[] = productId.split("&");
		
		logger.info("==★====★★★★★★★====★==主商户注册操作【6】：添加主商户产品关系");
		for (String pId : productIds) {
			error = addMerProduct(pId, merInf);
			if (StringUtil.isNotEmpty(error)) {
				logger.error("==★====★★★★★★★====★==主商户注册操作【6】：添加主商户产品关系，操作失败");
				return "添加产品关系信息失败";
			}
		}
		
		logger.info("==★====★★★★★★★★★====★==主商户注册操作【7】：配置基础产品费率信息");
		for (String pId : productIds) {
			error = allocationRate(pId, merInf);
			if (StringUtil.isNotEmpty(error)) {
				logger.info("==★====★★★★★★★★★====★==主商户注册操作【7】：配置基础产品费率信息，操作失败");
				return "配置产品费率信息失败";
			}
		}
		
		logger.info("==★====★★★★★★★★★====★==主商户注册操作【8】：配置主商户与联动商户号的银商关系");
		error = addMerBank(merInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★★====★==主商户注册操作【8】：配置主商户与联动商户号的银商关系，操作失败");
			return "添加商户支付服务商失败";
		}
		
		return null;
	}
	
	
	/**
	 * 店铺开通子流程
	 * 1、添加商户正式信息
	 * 2、添加商户账户信息
	 * 3、添加商户辅助信息
	 * 4、添加商户配置、生成证书
	 * 5、添加商户对账信息
	 * @param storeInf 店铺详情
	 * @throws Exception
	 */
	public String registerStoreJoin(StoreInf storeInf){
		String error = "";
		logger.info("==★====★====★==子商户注册操作【1】：添加子商户正式信息");
		error = insertMerInfoAndEx(storeInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★====★==子商户注册操作【1】：添加子商户正式信息操作失败");
			return "添加商户正式信息失败";
		}
		
		logger.info("==★====★★====★==子商户注册操作【2】：添加子商户账户信息");
		error = toOpenMerAccount(storeInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★====★==子商户注册操作【2】：添加子商户账户信息操作失败");
			return "添加商户账户信息失败";
		}
		
		logger.info("==★====★★★====★==子商户注册操作【3】：添加子商户辅助信息");
		error = addSysPara(storeInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★====★==子商户注册操作【3】：添加子商户辅助信息操作失败");
			return "添加商户辅助信息失败";
		}
		
		logger.info("==★====★★★★★====★==子商户注册操作【4】：添加子商户配置、生成证书");
		error = addMerCnf(storeInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★★★====★==子商户注册操作【4】：添加子商户配置、生成证书，操作失败");
			return "添加商户配置、生成证书失败";
		}
		
		logger.info("==★====★★★★★★====★==子商户注册操作【5】：添加子商户对账信息");
		error = addMerRecon(storeInf);
		if (StringUtil.isNotEmpty(error)) {
			logger.error("==★====★★★★★★====★==子商户注册操作【5】：添加子商户对账信息，操作失败");
			return "添加商户对账信息失败";
		}
		
		return null;
	}
	
	
	/**
	 * 子商户注册操作【1】：添加子商户正式信息
	 * @param storeInf 店铺详情
	 * @throws Exception
	 */
	public String insertMerInfoAndEx(StoreInf storeInf){
		com.umpay.operation.common.ReqMessage reqFind = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage merInfoResForSearch = null;
		reqFind.put("merId",storeInf.getStoreId());
		try {
			merInfoResForSearch = merInfoServiceRemote.getMerInfoAndMerExInfo(reqFind);
		} catch (Exception e) {
			logger.error("==★====★====★==子商户注册操作【1】：添加子商户正式信息异常");
			return "【1】：搜索商户和商户扩展信息失败！";
		}
		// 获取商户信息和扩展成功后
		if (!"0000".equals(merInfoResForSearch.getRetCode())) {
			logger.info("==★====★====★==子商户注册操作【1】：添加子商户正式信息失败");
			return "【1】：搜索商户和商户扩展信息失败！";
		}
		com.umpay.operation.model.merInfo.MerInfo mInfo = (com.umpay.operation.model.merInfo.MerInfo) merInfoResForSearch.getValue("merInfo");
		//com.umpay.operation.model.merInfo.MerInfoEx mInfoEx = (com.umpay.operation.model.merInfo.MerInfoEx) merInfoResForSearch.getValue("merInfoEx");
		if(mInfo == null){
			com.umpay.operation.common.ReqMessage reqAdd = ReqMessageUtil.makeOpReq();
			MerInfo merInfo = new MerInfo();
			merInfo.setMerId(storeInf.getStoreId());	//商户编号
			if (StringUtil.isNotEmpty(storeInf.getMerId())) {
				merInfo.setMerName(storeInf.getStoreShortName());	//如果是店铺则传商户名称
			}else {
				merInfo.setMerName(storeInf.getPayeeName());	//如果是主商户则传收款人姓名
			}
			merInfo.setCusPhone(storeInf.getPayeeMobileId());	//手机
			merInfo.setState(Short.valueOf("2"));	//状态:2-注册，4注销
			merInfo.setExMerId(storeInf.getMerId());
			merInfo.setMerType(storeInf.getStoreType());	//商户类型
			merInfo.setAddress(storeInf.getStoreFullAddr());	//地址
			merInfo.setModUser("0");	//修改人
			merInfo.setTimeLtd("0");	//次限额
			merInfo.setIsSpecial("0");	//1-是特殊商户,不累计消费额的商户(如缴手机话费、空中充值) 0-普通商户,需累计交易额做用户限额控制
			//客服电话
			merInfo.setCusPhone(storeInf.getPhone());	//6客服电话
			Map<String, Object> merInfMap;
			try {
				merInfMap = SaasPropertyUtil.javaBeanToMapO(merInfo);
			} catch (Exception e) {
				return "【1】：搜索商户和商户扩展信息失败！";
			}
			
			MerInfoEx merInfoEx = new MerInfoEx();
			merInfoEx.setMerId(storeInf.getStoreId());	//商户编号
			
			//传一级代理商编号			
			Map<String, Object> crmResult =null;
			Map<String, Object> params = ReqMessageUtil.makeReqCrmMap();
			params.put(CommonConsts.AGENTID, storeInf.getAgentId());
			params.put(CommonConsts.RELTYPE, "4");//	查询所有上级	
			try{
				XStream xstream = new XStream(new DomDriver());
				// URL配置文件取 --日志
	 			String url=UmfPropModel.INSTANCE.getPropValue("agent.crm.queryAgentRel");			
	 			logger.info("【查询代理商多级关系接口】入参url：" + url);
				logger.info("【查询代理商多级关系接口】入参params：" + params);
				crmResult =  (Map<String, Object>) com.umfwechat.util.HttpUtil.getResObjPost(url, xstream, params);	 
				logger.info("【查询代理商多级关系接口】出参：params" + crmResult);
			}catch(Exception e){
				logger.error("==★====★====★==子商户注册操作【1】：查询一级代理商信息失败");
				return "查询一级代理商信息失败！";
			}
			String retCode = (String) crmResult.get(CommonConsts.RETCODE);
			if (!RetCode.SUCCESS.equals(retCode)){
				logger.error("==★====★====★==子商户注册操作【1】：查询一级代理商信息失败");
				return "查询一级代理商信息失败！";
			}
			Map<String, Object> agentMetaMap =  (Map<String, Object>) crmResult.get("agentMetaMap");
			List s  = (List) agentMetaMap.get("agent[1]List");//取出一级代理商
			if(s == null && s.get(0)== null){
				logger.error("==★====★====★==子商户注册操作【1】：查询一级代理商信息失败");
				return "查询一级代理商信息失败！";
			}
			merInfoEx.setAgentId(s.get(0).toString());//赋值为次代理商的一级代理商
			logger.info("子商户注册操作【1】当前的代理商ID" + storeInf.getAgentId());
			logger.info("子商户注册操作【1】插入的一级代理商ID" + s.get(0).toString());
			
//			merInfoEx.setAgentId(storeInf.getAgentId());	//代理商ID
			
			merInfoEx.setLawyer(storeInf.getCategoryManName());	//法人
			merInfoEx.setLicenseNo(storeInf.getLicenseNo());	//营业执照编号

			if (StringUtil.isNotEmpty(storeInf.getMerId())) {
				String[] industrys = storeInf.getStoreCategory().split("&");
				merInfoEx.setIndustryTypeId(industrys[0]);	//行业大类(一级)
				merInfoEx.setIndustryIdSecond(industrys[1]);	//行业(二级)
				if (industrys.length >2) {
					merInfoEx.setIndustrySonTypeId(industrys[2]);	//行业子类V(三级)
				}
			}
			String industryId = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","industryId");
			String LEADER_GROUP_ID = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","LEADER_GROUP_ID");
			String LEADER_SELL_ID = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","LEADER_SELL_ID");
			logger.info("【获取配置文件】行业：" + industryId + "；主管团队：" + LEADER_GROUP_ID + "；主管销售：" + LEADER_SELL_ID);
			merInfoEx.setIndustryId(industryId);	//行业
			merInfoEx.setLeaderGroupId(LEADER_GROUP_ID);	//主管团队
			merInfoEx.setLeaderSellId(LEADER_SELL_ID);	//主管销售
			
			merInfoEx.setLinkName(storeInf.getPayeeName());	//联系人姓名
			merInfoEx.setTelephone(storeInf.getPayeeMobileId());	//手机
			merInfoEx.setAcceptChl(Short.valueOf("0"));	//拓展渠道0 商户自发起 1 销售拓展 2 拓展商推荐
			merInfoEx.setCorpName(storeInf.getStoreFullName());	//企业名称
			merInfoEx.setRgstAddress(storeInf.getRgstaddress());	//注册地址
			merInfoEx.setCertCode(DesIDUtil.decID(storeInf.getCategoryManCardno()));	//法人身份证
			//商户邮箱
			merInfoEx.setEmail(storeInf.getEmail());
			Map<String, Object> merInfoExMap;
			try {
				merInfoExMap = SaasPropertyUtil.javaBeanToMapO(merInfoEx);
			} catch (Exception e) {
				return "【1】：搜索商户和商户扩展信息失败！";
			}
			
			reqAdd.putAll(merInfMap);
			reqAdd.putAll(merInfoExMap);
		//~~~~~~~~~~SKS00000074工单，修复运营平台黑名单Bug
			if ("1".equals(storeInf.getStoreType())) {//商户类型：0小微；1个体
				reqAdd.put("corpName",storeInf.getStoreFullName());//企业全称
				reqAdd.put("corpCertiCode",storeInf.getLicenseNo());//企业证件号（营业执照编号）
				reqAdd.put("lawPersonCertiCode",storeInf.getCategoryManCardno());//法人代表证件号
			}else {
				reqAdd.put("corpName",storeInf.getPayeeInidcard());//企业全称（小微全传：收款人身份证号）
				reqAdd.put("corpCertiCode",storeInf.getPayeeInidcard());//企业证件号（营业执照编号）（小微全传：收款人身份证号）
				reqAdd.put("lawPersonCertiCode",storeInf.getPayeeInidcard());//法人代表证件号（小微全传：收款人身份证号）
			}
			logger.info("【添加商户正式信息】入参" + reqAdd);
		//~~~~~~~~~~SKS00000074工单，修复运营平台黑名单Bug
			com.umpay.operation.common.ResMessage merInfoResForInsert = merInfoServiceRemote.addMerInfoAndMerExInfo(reqAdd);
			if (!"0000".equals(merInfoResForInsert.getRetCode())) {
				logger.info("==★====★====★==子商户注册操作【1】：添加子商户正式信息失败");
				return "【1】：搜索商户和商户扩展信息失败！";
			}
		}
		return null;
	}
	
	/**
	 * 子商户注册操作【2】：添加商户账户信息
	 * @param storeInf 店铺详情
	 * @throws Exception
	 */
	public String toOpenMerAccount(StoreInf storeInf){
		String url = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","ACCOUNT_FRONT_URL", "");	//获取调用的账户前置链接
		logger.info("调用的账户前置链接：" + url);
		Map<String,Object> reqMap = new HashMap<String, Object>();
		Map<String, Object> resMap = new HashMap<String, Object>();
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		reqMap.put("rpid", req.getRpid());
		reqMap.put("reqDate", TimeUtil.date8());
		reqMap.put("reqTime", TimeUtil.time6());
		reqMap.put("brc","01");	//所属中心 01电商
		reqMap.put("instId","20000008"); //机构号
		/**
		 * 查询商户账户信息
		 */
		reqMap.put("funCode", "0302");	//查询
		reqMap.put("actorId", storeInf.getStoreId());
		reqMap.put("actorType", "2");	//4：体系内部  3：金融机构  2：企业商户  1：个人用户
		try {
			resMap = HttpUtil.httpPostXml2Xml(url, reqMap);
		} catch (Exception e) {
			logger.error("==★====★★====★==子商户注册操作【2】：添加子商户账户信息异常");
			return "【2】：添加子商户账户信息错误！";
		}
		if(!"0000".equals(resMap.get("retCode"))){
			/**
			 * 添加商户账户
			 */
			reqMap.put("trace", PmUtils.randomRpId14()+"00"); //发起方流水号(14位流水号，不足补0)
			reqMap.put("merId",storeInf.getStoreId());	//店铺编号
			if (!"".equals(storeInf.getMerId()) && storeInf.getMerId() != null) {
				reqMap.put("realMerid",storeInf.getMerId()); //归属商户号（子商户时传MerId）
			}else {
				reqMap.put("realMerid", storeInf.getStoreId());	//归属商户号（主商户时传自己）
			}
			reqMap.put("prodId","P0000001");	//产品号
			reqMap.put("funCode","0102");	//添加
			try {
				resMap = HttpUtil.httpPostXml2Xml(url, reqMap);
			} catch (Exception e) {
				logger.error("==★====★★====★==子商户注册操作【2】：添加子商户账户信息异常");
				return "【2】：添加子商户账户信息错误！";
			}
			if(!"0000".equals(resMap.get("retCode"))){
				logger.error("==★====★★====★==子商户注册操作【2】：添加子商户账户信息失败");
				return "【2】：添加子商户账户信息错误！";
			}
		}
		
		return null;
	}
	
	/**
	 * 子商户注册操作【3】：添加子商户辅助信息
	 * @param storeInf	店铺详情
	 * @throws Exception
	 */
	public String addSysPara(StoreInf storeInf){
		/**
		 * 通过主键查询商户辅助信息
		 */
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		try {
			req.put("tpId","UniformPay");	//进程标识
			req.put("tpName","MerAcl" + "." + storeInf.getStoreId()); // 子商户ID
			res = sysParaServiceRemote.getSysParabyTpidAndTpname(req);
		} catch (Exception e) {
			logger.error("==★====★★====★==子商户注册操作【3】：调用获取商户辅助信息接口异常");
			return "【3】：调用获取商户辅助信息失败！";
		}
		if (!"0000".equals(res.getRetCode())) {
			logger.info("==★====★====★==子商户注册操作【3】：调用获取商户辅助信息失败");
			return "【3】：添加子商户辅助信息失败";
		}
		if(res.getValue("resSysPara") == null){
			/**
			 * 添加商户辅助信息
			 */
			req.put("tpValue","0");
			req.put("detail","0");
			try {
				res = sysParaServiceRemote.addSysPara(req);
			} catch (Exception e) {
				logger.error("==★====★====★==子商户注册操作【3】：添加子商户辅助信息异常");
				return "【3】：添加子商户辅助信息失败";
			}
			if(!"0000".equals(res.getRetCode())){
				logger.info("==★====★====★==子商户注册操作【3】：添加子商户辅助信息失败");
				return "【3】：添加子商户辅助信息失败";
			}
		}
		return null;
	}
	
	/**
	 * 子商户注册操作【4】：添加子商户配置、生成证书
	 * @param storeInf
	 * @throws Exception
	 */
	public String addMerCnf(StoreInf storeInf){
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		req.put("merId",storeInf.getStoreId());
		try {
			/**
			 * 查询商户配置、证书是否存在
			 */
			res = merCnfServiceRemote.getMerCnfByMerId(req);
		} catch (Exception e) {
			logger.error("==★====★====★==子商户注册操作【4】：查询商户配置异常");
			return "【4】：添加子商户配置、生成证书失败";
		}
		if(!"0000".equals(res.getRetCode())){
			logger.info("==★====★====★==子商户注册操作【4】：查询商户配置失败");
			return "【4】：添加子商户配置、生成证书失败";
		}
		MerCnf merCnf = (MerCnf) res.getResMap().get("merCnf");
		if (merCnf == null) {
			/**
			 * 创建证书
			 */
			Map<String, Object> returnMap = createCertificate(storeInf.getStoreId());	//创建证书，现在创建证书不使用“商户名称”字段
			if (!"0000".equals(returnMap.get("retCode"))) {
				logger.info("==★====★====★==子商户注册操作【4】：创建证书失败");
				return "【4】：添加子商户配置、生成证书失败";
			}
			try {
				/**
				 * 商户配置
				 */
				req.put("merger","1");	// 合并模式
				req.put("version","3.0");	//版本号
				req.put("notifyMode","21");	//通知模式
				req.put("notifyTimes","3");	//通知次数
				req.put("spCardPay","0");	//是否支持点卡兑换券
				req.put("defBankType","2");	//默认付款方式
				req.put("notifyMethod","0");	//后台通知方式
				req.put("retMethod","1");	//前台通知方式
				req.put("expireTime","86400");
				Timestamp now = new Timestamp(System.currentTimeMillis());
				req.put("inTime",now);
				req.put("modTime",now);
				req.put("modUser","saas");
				// 证书转byte类型
				String merCertFileRoute = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","MerCer.server.shareDirectory", "");	//证书路径
				File[] merCert = new File(merCertFileRoute + storeInf.getStoreId()).listFiles();
				File merCertf = null;
				for (File m : merCert) {
					if (m.getName().lastIndexOf("crt") > -1) {
						merCertf = m;
					}
				}
				// merCnfInData.setCertName(merCertf.getName());
				byte[] b = new byte[(int) merCertf.length()];
				FileInputStream fis = new FileInputStream(merCertf);
				fis.read(b);
				fis.close();
				req.put("merCert",b);
				res = merCnfServiceRemote.addMerCnf(req);
			} catch (Exception e) {
				logger.error("==★====★====★==子商户注册操作【4】：添加子商户配置异常");
				return "【4】：添加子商户配置、生成证书失败";
			}
			if(!"0000".equals(res.getRetCode())){
				logger.info("==★====★====★==子商户注册操作【4】：添加子商户配置失败");
				return "【4】：添加子商户配置、生成证书失败";
			}
		}
		return null;
	}
	
	/**
	 * 创建证书
	 * @param merId
	 * @param merName
	 * @return
	 */
	public Map<String, Object> createCertificate(String merId) {
		logger.info("【生成证书】 start。");
		Long startTime = System.currentTimeMillis();
		Map<String, Object> returnMap = new HashMap<String, Object>();
		String scriptDirectory = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties", "MerCer.server.scriptDirectory", "");
		String newCertificateName = merId + "_"; // 将商户证书的名称由商户号_商户名格式，改为商户号_
		InputStream in = null;
		try {
			Process pro = Runtime.getRuntime().exec(new String[] { "sh", "-c", scriptDirectory + " " + newCertificateName });
			logger.info("执行脚本：" + scriptDirectory + newCertificateName);
			pro.waitFor();
			in = pro.getInputStream();
			BufferedReader read = new BufferedReader(new InputStreamReader(in));
			String result = read.readLine();
			logger.info("执行命令返回结果:" + result);
			returnMap.put("retMsg", "创建【商户证书】成功！");
			returnMap.put("retCode", "0000");
		} catch (Exception e) {
			logger.error("生成key执行命令错误:", e);
			returnMap.put("retMsg", "生成key执行命令错误！");
			returnMap.put("retCode", "00060701");
		}

		logger.info("【生成证书】 end，耗时 = " + (System.currentTimeMillis() - startTime) + " 毫秒。");
		return returnMap;
	}
	
	/**
	 * 子商户注册操作【5】：添加子商户对账信息
	 * @param storeInf
	 * @throws Exception
	 */
	public String addMerRecon(StoreInf storeInf){
		com.umpay.operation.common.ReqMessage reqQuery = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		reqQuery.put("colId", "stdPay4.0");	//对账版本
		reqQuery.put("merId",storeInf.getStoreId());
		reqQuery.put("currentPage","1");
		reqQuery.put("pageSize","100");
		try {
			/**
			 * 查询商户对账信息
			 */
			res = colInfoRemote.pageQuerMerCol(reqQuery);
		} catch (Exception e) {
			logger.error("==★====★★★★★★====★==子商户注册操作【5】：添加子商户对账信息异常");
			return "【5】：查询商户对账信息失败";
		}
		if(!"0000".equals(res.getRetCode())){
			logger.info("==★====★====★==子商户注册操作【5】：添加子商户对账信息执行失败");
			return "【5】：查询商户对账信息失败";
		}
		Integer totalSize = (Integer) res.getResMap().get("totalSize");
		if(totalSize == 0){
			/**
			 * 添加商户对帐信息
			 */
			com.umpay.operation.common.ReqMessage reqAdd = ReqMessageUtil.makeOpReq();
			reqAdd.put("colId", "stdPay4.0");
			reqAdd.put("merId",storeInf.getStoreId());
			reqAdd.put("status","1");
			reqAdd.put("modUser","saas");
			try {
				res = colInfoRemote.addMerCol(reqAdd);
			} catch (Exception e) {
				logger.error("==★====★★★★★★====★==子商户注册操作【5】：添加子商户对账信息异常");
				return "【5】：添加子商户对账信息失败";
			}
			if(!"0000".equals(res.getRetCode())){
				logger.info("==★====★====★==子商户注册操作【5】：添加子商户对账信息失败");
				return "【5】：添加子商户对账信息失败";
			}
		}
		return null;
	}
	
	/**
	 * 子商户注册操作【6】：添加子商户产品关系
	 * @param storeInf
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String addMerProduct(String pId, StoreInf storeInf){
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		req.put("merId",storeInf.getStoreId());	//商户ID
		req.put("productId",pId);	//产品ID
		try {
			/**
			 * 通过商户ID和产品ID，查看商户产品的绑定关系
			 */
			res = merProductServiceRemote.getMerProductByKey(req);
		} catch (Exception e) {
			logger.error("==★====★★★★★★====★==子商户注册操作【6】：查询商户产品的绑定关系异常");
			return "【6】：查询商户产品的绑定关系失败";
		}
		if(!"0000".equals(res.getRetCode())){
			logger.info("==★====★★★★★★====★==子商户注册操作【6】：查询商户产品的绑定关系失败");
			return "【6】：查询商户产品的绑定关系失败";
		}
		MerProduct merProduct = (MerProduct) res.getResMap().get("merProduct");
		if(merProduct == null){
			/**
			 * 添加商户产品绑定关系
			 */
			//调用CRM进行创建关系
			Map<String, Object> reqMap = new HashMap<String, Object>();
			String payElement = "";// 支付元素
			String ptype = pId.substring(3, 4); // 取产品号中付款标志位
			if (ptype.equals("5") || ptype.equals("7")) { // 信用卡无磁无密支付，信用卡无磁无密预授权
				payElement = "010203"; // 设置支付要素（cvv）
			} else if (ptype.equals("6")) { // 借记卡无磁无密支付
				payElement = "01";
			} else if (ptype.equals("4")) { // U付账户支付
				payElement = "";
			} else if ("P0000001".equals(pId) || "P0000002".equals(pId)) {
				payElement = "";
			} else {
				payElement = "";
			}
			reqMap.put("rpid", req.getRpid());
			reqMap.put("funCode","QYZH");	//
			reqMap.put("merId",storeInf.getStoreId());	//商户ID
			reqMap.put("accTypeTag", "2");	//开户类型
			reqMap.put("productId", pId);	//产品ID
			reqMap.put("playelements", payElement);
			reqMap.put("RegPointTag", "40");	//开通渠道
			reqMap.put("sendSMS", "2");
			Map<String, Object> crmResult = null;
			String retCode = "";
			try {
				XStream xstream = new XStream(new DomDriver());
				// URL配置文件取
				String url = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","upay.crm.account.url", "");	//获取商户产品绑定关系URL
				//调用受理注销用户标识接口
				crmResult = (Map<String, Object>) HttpHelper.getResObjPost(url, xstream, reqMap);
				retCode = (String) crmResult.get("retCode");
				if (!"0000".equals(retCode)){
					logger.info("==★====★★★★★★====★==子商户注册操作【6】：请求CRM系统失败:添加商户产品的绑定关系失败");
					return "【6】：添加商户产品的绑定关系失败";
				}
			} catch (Exception e) {
				logger.error("==★====★★★★★★====★==子商户注册操作【6】：请求CRM系统失败:添加商户产品的绑定关系异常");
				return "【6】：添加商户产品的绑定关系失败";
			}
			if(crmResult==null || crmResult.isEmpty()) {
				logger.info("==★====★★★★★★====★==子商户注册操作【6】：请求CRM系统失败:添加商户产品的绑定关系失败");
				return "【6】：添加商户产品的绑定关系失败";
			}
		}
		return null;
	}
	
	/**
	 * 子商户注册操作【7】：添加子商户签约产品、基础产品费率信息
	 * @param pId
	 * @param storeInf
	 * @return
	 */
	public String allocationRate(String pId, StoreInf storeInf){
		ReqMessage req = ReqMessageUtil.makeSpReq();
		Map<String, Object> params = new HashMap<String, Object>();
		Map<String,Object> res=null;
		params.put("rpid", req.getRpid());
		params.put("reqDate", req.getReqDate());
		params.put("reqTime", req.getReqTime());
		params.put("merId",storeInf.getStoreId());	//商户号
		params.put("startDate",req.getReqDate());	//生效日期
		params.put("productId",pId);	//产品号
		params.put("actSettlType","2");	//记账结算类型
		params.put("feeRateType","11");	//费率类型
		params.put("feeRateValue","0");	//费率值
		params.put("minFee","1");	//保底费率（分）
		params.put("maxFee","0");	//封顶费率（分）
		params.put("isReturn","0");	//是否退换手续费
		params.put("modId", "spapply");
		try {
			String url = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties","ACC_FEE_URL", "");	//获取配置费率信息URL
			res = HttpUtil.httpPostForm2Xml(url, params);
		} catch (Exception e) {
			logger.error("==★====★====★==子商户注册操作【7】：添加子商户签约产品、基础产品费率信息异常");
			return "【7】：添加子商户产品费率信息失败";
		}
		if("0000".equals(res.get("retCode"))){	//成功
			return null;
		}else if ("00170020".equals(res.get("retCode"))) {	//费率配置已存在
			return null;
		}else {
			logger.info("==★====★====★==子商户注册操作【7】：添加子商户签约产品、基础产品费率信息失败");
			return "【7】：添加子商户产品费率信息失败";
		}
	}
	
	/**
	 * 子商户注册操作【8】：添加子商户支付服务商（配置子商户与联动商户号的银商关系）
	 * @param storeInf
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public String addMerBank(StoreInf storeInf){
		String bankId[] = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties", "BANKID_SAAS", "").split("&");	//支付服务商编号
		String bankMerId[] = PropertyUtil.getStrValue("umfWeChatPlat_appConf.properties", "BANKMERID_SAAS", "").split("&");	//平台在机构的商户号
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		com.umpay.operation.common.ResMessage res = null;
		for (int i = 0; i < bankId.length; i++) {
			/**
			 * 查询商户是否配置过支付服务商
			 */
			req.put("merId",storeInf.getStoreId());	//商户ID
			req.put("bankId",bankId[i]);	//支付服务商编号
			try {
				res = bankInfServiceRemote.queryMerbankByMerIdAndBankId(req);
			} catch (Exception e) {
				logger.error("==★====★====★==子商户注册操作【8】：添加子商户支付服务商信息异常");
				return "【8】：添加子商户支付服务商息失败";
			}
			if (!"0000".equals(res.getRetCode())) {
				logger.info("==★====★====★==子商户注册操作【8】：添加子商户支付服务商信息失败");
				return "【8】：添加子商户支付服务商信息失败";
			}
			List<MerBankInf> merBankInfs = (List<MerBankInf>) res.getResMap().get("merBankInfList");
			if (merBankInfs.size() < 1) {
				req.put("bankInfs","[{'bankMerId':'" + bankMerId[i] +"','state':'2','merId':'" + storeInf.getStoreId() + "','bankId':'" + bankId[i] + "'}]");
				try {
					res = bankInfServiceRemote.insertMerBankInfBatch(req);
				} catch (Exception e) {
					logger.error("==★====★====★==子商户注册操作【8】：添加子商户支付服务商信息异常");
					return "【8】：添加子商户支付服务商信息失败";
				}
				if (!"0000".equals(res.getRetCode())) {
					logger.info("==★====★====★==子商户注册操作【8】：添加子商户支付服务商信息失败");
					return "【8】：添加子商户支付服务商信息失败";
				}
			}
		}
		return null;
	}
	
	
	/**
	 * 将错误信息插入审批流程表
	 * @param storeInf	店铺详情
	 * @param errorMsg	错误信息
	 * @return
	 */
	public com.umpay.operation.common.ResMessage addJoinFlowForCheckMer(StoreInf storeInf, String errorMsg){
		com.umpay.operation.common.ResMessage res = null;
		com.umpay.operation.common.ReqMessage req = ReqMessageUtil.makeOpReq();
		//req.put("merId",storeInf.getStoreId());	//店铺ID
		req.put(CommonConsts.MERUNIFORMID,storeInf.getStoreId());	//商户唯一标识
		req.put("handleState","0");	//申请处理状态
		req.put("remark",errorMsg);	//备注
		req.put("handleUser","0");	//处理人
		req.put("handleRole","00");	//处理人角色：00系统自动；01财务； 02运营； 03客服 ；04商户 ；99其他
		try {
			res = joinFlowServiceRemote.addJoinFlowForCheckMer(req);
		} catch (Exception e) {
			res.put("retCode","0001");
			res.put("retMsg","插入审批流程异常");
		}
		return res;
	}
	/**
	 * 【发送邮件】
	 * @author zhaojiafu
	 * @param merName 
	 * @param merId 
	 * @date 2014-12-25
	 */
	
	public boolean sendEmail(StoreInf storeInf) {
		logger.info("【发送邮件】 start。");
		boolean retType = true;
		Long startTime = System.currentTimeMillis();		
		// 获取请求参数
		String merId = storeInf.getStoreId();
		String merName = storeInf.getStoreShortName();
		String emailTitle = "证书("+merName+"+"+storeInf.getPayeeName() +")";
		String addresseeEMail = storeInf.getEmail();
		String [] keyType = { "pem","der", "p8"};
		String [] certificateType =  { "crt","pem"};
		logger.info("请求参数 --- merId = " +  merId + ",merName"+ merName);
		logger.info("请求参数 --- emailTitle = " +  emailTitle + ", addresseeEMail = " +  addresseeEMail  + ", keyType = " + JSONArray.fromObject(keyType) + ", certificateType = " + JSONArray.fromObject(certificateType));	
		
		if(merId == null || "".equals(merId) || merName == null || "".equals(merName) || addresseeEMail == null || "".equals(addresseeEMail)){
			logger.info("【发送邮件】 参数请求不足");
			retType = false;
			return retType;
		}
		try{
			String fileName=UmfPropModel.INSTANCE.getPropValue("sendCertificate");	// 邮件内容模板
			logger.info("邮件内容模板路径 " +  fileName);
			// 组织
			Calendar calendar = Calendar.getInstance();
			Map<String, String> map = new HashMap<String, String>();
			map.put("merId", merId);
			map.put("merName", merName);
			map.put("YYYY", calendar.get(Calendar.YEAR) + "");
			map.put("MM", (calendar.get(Calendar.MONTH) + 1) + "");
			map.put("day", calendar.get(Calendar.DAY_OF_MONTH) + "");
			

			String shareDirectory = UmfPropModel.INSTANCE.getPropValue("MerCer.server.shareDirectory");
			String certDirectory =  UmfPropModel.INSTANCE.getPropValue("MerCer.server.userShareDirectory");
			logger.info("证书路径1 " +  shareDirectory);
			logger.info("证书路径2 " +  certDirectory);
			String newCertificateName = shareDirectory + merId + "/";		// key证书路径
			String userCertificateName = certDirectory;		//cert证书路径
			int num =  keyType.length +  certificateType.length;//文件个数
			String files = "";
			File dir=new File(newCertificateName);
			CaFilter caFilter = new CaFilter(merId);
			String[] names = dir.list(caFilter);//路径下所有文件
			File [] fileCertDirectory = new File(certDirectory).listFiles();
			List<String> fileList = new ArrayList<String>();
			//String [] attachFilePaths = new String[1024];
			logger.info("要发送的【商户证书】文件个数：" + num);
			for (int i=0; i< keyType.length; i++) {
				File tmp = new File(newCertificateName + merId + "_.key." + keyType[i]);
				if(tmp.exists()){
					fileList.add(newCertificateName + merId + "_.key." + keyType[i]);
				}
			}
			int k=0;
			if (keyType.length > 0) {
				for (int i=0; i< keyType.length; i++) {
					for (String name : names) {//遍历文件名，拼接路径和文件名
						logger.info("文件名：name ="+name);
							if(name.matches(merId+"_.+\\.key\\."+ keyType[i])){
							if(!fileList.contains(newCertificateName + merId + "_.key." + keyType[i])){
								fileList.add(newCertificateName + name);
								files += newCertificateName +name + " , ";
								k++;
							}
						}
					}
				}
			}
			if (certificateType.length>0) {
				for (int i= keyType.length, t=0; i<num; i++) {
					for(int j=0;j<fileCertDirectory.length;j++){
						if(StringUtil.trim(fileCertDirectory[j].getName()).indexOf(certificateType[t])>-1){
							//attachFilePaths[k] = userCertificateName + StringUtil.trim(fileCertDirectory[j].getName());
							fileList.add(userCertificateName + StringUtil.trim(fileCertDirectory[j].getName()));
							files += userCertificateName + StringUtil.trim(fileCertDirectory[j].getName()) + ",";
							k++;
						}
					}
					t++;
				}
			}
			logger.info("要发送的【商户证书】文件为，" + files);
			logger.info("要发送的【商户证书】附件为：" + fileList);	
			
			// 组织【邮件】参数
			String [] attachFilePaths1 = new String[fileList.size()];
			for(int i=0;i<fileList.size();i++){
				attachFilePaths1[i]=fileList.get(i);
			}
			MailSenderInfo mailSenderInfo = new MailSenderInfo();
			mailSenderInfo.setAttachFilePaths(attachFilePaths1);//发送所选择的证书
			mailSenderInfo.setSubject( emailTitle);
			mailSenderInfo.setToAddress(addresseeEMail);
			
			EmailXmlUtil.emailXmlRead(fileName, mailSenderInfo, map);
			String emailContent = mailSenderInfo.getContent();
			for (String s : map.keySet()) {	
				emailContent = emailContent.replaceFirst(s, map.get(s));
			}
			mailSenderInfo.setContent(emailContent);
			boolean isCg = SendMailUtil.sendHtmlMail(mailSenderInfo);			
			if (isCg) {
				logger.info("【发送邮件】成功！");
				retType = true;
			} else {
				logger.info("【发送邮件】失败！");
				retType = false;
			}
		} catch (Exception e) {
			logger.error("发送邮件失败！" , e);
			retType = false;
		}
		
		logger.info("【发送邮件】 end，耗时 = " + (System.currentTimeMillis() - startTime) + " 毫秒。");
		return retType;
	}
	
	/**
	 * 调用CRM 同步客户信息
	 * @param merId
	 * @param merName
	 */
	private void createCust(String merId,String merName) {
		//调用CRM 同步客户信息
		Map<String, Object> crmCreateCustMap = ReqMessageUtil.makeReqCrmMap();
		crmCreateCustMap.put("mainMerId", merId);//主商户号
		crmCreateCustMap.put("mainMerName", merName);//主商户名称,传值为收款人姓名
		crmCreateCustMap.put("custState", "0");//客户状态
		crmCreateCustMap.put("businessTag", "SAAS");//业务线标识
		String rpid = (String)crmCreateCustMap.get("rpid");
		String url=UmfPropModel.INSTANCE.getPropValue("crm.createCust");
		boolean emailSendFlag = false;
		String failedContent = "";
		String CRMOperation ="";
		try {
			CRMOperation = "CRM同步客户信息";
			logger.info(String.format("----★----★--请求CRM同步客户信息接口:参数[%s]====URL[%s]", crmCreateCustMap,url));
			RequestUtil requestUtil = new RequestUtil();//请求CRM工具类
			Map<String,Object> crmResMap=(Map<String, Object>) requestUtil.sendRequestForPost(url,crmCreateCustMap);
			if(crmResMap==null||crmResMap.size()<1){
				logger.info("----★----★--调用CRM同步客户信息接口:失败,rpid+"+StringUtil.trim(rpid));
				failedContent="接口调用失败";
				emailSendFlag = true;
			}
			else if(ConstEC.SUCCESS.equals(crmResMap.get(XmlData.RETCODE))){
				logger.info("----★----★--CRM同步客户信息:成功,rpid="+StringUtil.trim(rpid));
			}
			else{
				logger.info("----★----★--CRM同步客户信息:失败,rpid="+StringUtil.trim(rpid)+",crmResMap="+crmResMap.toString());
				failedContent=crmResMap.toString();;
				emailSendFlag = true;
			}
		} catch (Exception e) {
			logger.error("----★----★--CRM同步客户信息:失败,rpid="+StringUtil.trim(rpid)+",异常信息：", e);
			failedContent = e.getMessage();
			emailSendFlag = true;
		}
		if(!emailSendFlag){ //如果CRM同步客户信息成功，再调用CRM同步商户客户关系
			/*调用CRM同步商户客户关系*/
			Map<String, Object> createMerCustRelMap = new HashMap<String, Object>();
			createMerCustRelMap.put(XmlData.RPID, StringUtil.trim(rpid));//请求流水
			createMerCustRelMap.put("mainMerId", merId);//主商户号
			createMerCustRelMap.put("mainMerName", merName);//主商户名称
			createMerCustRelMap.put("followMerId", merId);//子商户号  （注：主商户关系绑定，此处传主商户号）
			createMerCustRelMap.put("followMerName", merName);//子商户名称   （注：因为t_mer_inf表中，子商户信息mername与主商户mername相同，所以此处保持与主账户名称一致）
			createMerCustRelMap.put("merCustState", "0");//商户客户关系状态
			createMerCustRelMap.put("businessTag", "SAAS");//业务线标识
			try {
				CRMOperation = "CRM同步商户客户关系(主商户)";
				String createMerCustRelURL = UmfPropModel.INSTANCE.getPropValue("crm.createMerCustRel");//CRM URL
				logger.info(String.format("----★----★--请求CRM同步商户客户关系接口:参数[%s]====URL[%s]", createMerCustRelMap,createMerCustRelURL));
				RequestUtil requestUtil = new RequestUtil();//请求CRM工具类
		        Map<String,Object> crmResMap=(Map<String, Object>) requestUtil.sendRequestForPost(createMerCustRelURL,createMerCustRelMap);
		        if(crmResMap==null||crmResMap.size()<1){
		        	logger.info("----★----★--调用CRM同步商户客户关系接口:失败,rpid+"+StringUtil.trim(rpid));
		        	failedContent = "接口调用失败";
		        	emailSendFlag = true;
		        }
		        else if(ConstEC.SUCCESS.equals(crmResMap.get(XmlData.RETCODE))){
		        	logger.info("----★----★--CRM同步商户客户关系:成功,rpid="+StringUtil.trim(rpid));
		        }
		        else{
		        	logger.info("----★----★--CRM同步商户客户关系:失败,rpid="+StringUtil.trim(rpid)+",crmResMap="+crmResMap.toString());
		        	failedContent = crmResMap.toString();
		        	emailSendFlag = true;
		        }
			} catch (Exception e) {
				logger.error("----★----★--CRM同步商户客户关系:失败,rpid="+StringUtil.trim(rpid)+",异常信息：", e);
				failedContent = e.getMessage();
				emailSendFlag = true;
			}	
		}
		//CRM同步客户信息失败，发邮件通知负责人手动同步客户信息
		if(emailSendFlag){
			logger.info("进入发送邮件任务");
			String mailSender=UmfPropModel.INSTANCE.getPropValue("crm.failed.notify.email");
			String subject = CRMOperation+"失败";
			String mailContent = String.format("您好,主商户[merId=%s]入网审核,操作步骤[%s],[rpid=%s],时间[%s],失败信息:%s",merId,CRMOperation,rpid,new Date().toString(),failedContent);
			logger.info("邮件内容"+mailContent);
			SendMailUtil.sendMail(mailSender, subject, mailContent);
		}
	}
	/**
	 * 调用CRM同步商户客户关系
	 * @param merId
	 * @param merName
	 * @param storeId
	 * @param storeName
	 */
	private void createMerCustRel(String merId,String merName,String storeId,String storeName) {
		//调用CRM同步商户客户关系
		Map<String, Object> reqMap = ReqMessageUtil.makeReqCrmMap();
		reqMap.put("mainMerId", StringUtil.trim(merId));//主商户号
		reqMap.put("mainMerName", StringUtil.trim(merName));//主商户名称
		reqMap.put("followMerId", storeId);//子商户号
		reqMap.put("followMerName", storeName);//子商户名称
		reqMap.put("merCustState", "0");//商户客户关系状态
		reqMap.put("businessTag", "SAAS");//业务线标识
		String url=UmfPropModel.INSTANCE.getPropValue("crm.createMerCustRel");
		boolean emailSendFlag = false;
		String failedContent = "";
		try {
			logger.info(String.format("----★----★--请求CRM同步商户客户关系接口:参数[%s]====URL[%s]", reqMap,url));
			RequestUtil requestUtil = new RequestUtil();//请求CRM工具类
			Map<String,Object> crmResMap=(Map<String, Object>) requestUtil.sendRequestForPost(url,reqMap);
			if(crmResMap==null||crmResMap.size()<1){
				logger.info("----★----★--调用CRM同步商户客户关系接口:失败,rpid+"+StringUtil.trim(reqMap.get("rpid")));
				failedContent = "接口调用失败";
				emailSendFlag = true;
			}
			else if(ConstEC.SUCCESS.equals(crmResMap.get(XmlData.RETCODE))){
				logger.info("----★----★--CRM同步商户客户关系:成功,rpid="+StringUtil.trim(reqMap.get("rpid")));
			}
			else{
				logger.info("----★----★--CRM同步商户客户关系:失败,rpid="+StringUtil.trim(reqMap.get("rpid"))+",crmResMap="+crmResMap.toString());
				failedContent = crmResMap.toString();
				emailSendFlag = true;
			}
		} catch (Exception e) {
			logger.error("----★----★--CRM同步商户客户关系:失败,rpid="+StringUtil.trim(reqMap.get("rpid"))+",异常信息：", e);
			failedContent = e.getMessage();
			emailSendFlag = true;
		}
		//CRM同步商户客户关系失败，发邮件通知负责人手动同步商户客户关系
		if(emailSendFlag){
			logger.info("进入发送邮件任务");
			String mailSender=UmfPropModel.INSTANCE.getPropValue("crm.failed.notify.email");
			logger.info("收件人地址="+mailSender);
			String subject="CRM同步商户客户关系失败";
			String mailContent = String.format("您好,主商户[merId=%s]开通应用子商户[storeId=%s],CRM同步商户客户关系失败,[rpid=%s],时间[%s],失败信息:%s",merId,storeId,reqMap.get("rpid"),new Date().toString(),failedContent);
			logger.info("邮件内容"+mailContent);
			SendMailUtil.sendMail(mailSender, subject, mailContent);
		}

	}
}
